package com.huiyou.adminapi.common;

import com.alibaba.fastjson.JSONObject;
import com.huiyou.adminapi.common.utils.DateUtil;


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Request {

    //云市场分配的密钥Id
    private final static String secretId = "AKIDh20wlGEEZKDe5vU4m0HVVh8XlO79rdNKNJ9s";
    //云市场分配的密钥Key
    private final static String secretKey = "KPwVt9673VN1EEAPEoOJ8105aDuQF86c9e3zpX4";
    private final static String source = "huiyou";

    private final static String URI = "https://service-53e769xh-1255468759.ap-shanghai.apigateway.myqcloud.com/release/iparea";

    private static String calcAuthorization(String datetime) {
        String signStr = "x-date: " + datetime + "\n" + "x-source: " + Request.source;
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        Key sKey = new SecretKeySpec(Request.secretKey.getBytes(StandardCharsets.UTF_8), mac.getAlgorithm());
        try {
            mac.init(sKey);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        byte[] hash = mac.doFinal(signStr.getBytes(StandardCharsets.UTF_8));
        String sig = Base64.getEncoder().encodeToString(hash);

        return "hmac id=\"" + Request.secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\"";
    }

    private static String urlEncode(Map<String, ?> map) {
        StringBuilder sb = new StringBuilder();
        map.forEach((key, value) -> {
            if (sb.length() > 0) {
                sb.append("&");
            }
            try {
                sb.append(String.format("%s=%s",
                        URLEncoder.encode(key, "UTF-8"),
                        URLEncoder.encode(value.toString(), "UTF-8")));
            } catch (UnsupportedEncodingException e) {
                log.error("url encode fail");
            }
        });
        return sb.toString();
    }

    public static JSONObject getAddress(String ip) {

        if (!ipValidation(ip)) {
            return null;
        }

        String datetime = DateUtil.dateTime();
        // 签名
        String auth = calcAuthorization(datetime);
        // 请求方法
        String method = "GET";
        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("X-Source", source);
        headers.put("X-Date", datetime);
        headers.put("Authorization", auth);

        // 查询参数
        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("ip", ip);
        // body参数
        Map<String, String> bodyParams = new HashMap<>();

        // url参数拼接
        String url = Request.URI;
        if (!queryParams.isEmpty()) {
            url += "?" + urlEncode(queryParams);
        }

        BufferedReader in = null;
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setRequestMethod(method);

            // request headers
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }

            // request body
            Map<String, Boolean> methods = new HashMap<>();
            methods.put("POST", true);
            methods.put("PUT", true);
            methods.put("PATCH", true);
            Boolean hasBody = methods.get(method);
            if (hasBody != null) {
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

                conn.setDoOutput(true);
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                out.writeBytes(urlEncode(bodyParams));
                out.flush();
                out.close();
            }

            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            StringBuilder result = new StringBuilder();
            while ((line = in.readLine()) != null) {
                result.append(line);
            }

            //            return json.getString("city") + "-" + json.getString("county");
            return JSONObject.parseObject(result.toString()).getJSONObject("showapi_res_body");
        } catch (Exception e) {
            log.error("获取区域失败");
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                log.error("IO 关闭失败");
            }
        }
        return null;
    }

    private static boolean ipValidation(String ipStr) {
        Pattern pattern = Pattern.compile("((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$");
        Matcher matcher = pattern.matcher(ipStr);
        return matcher.find();
    }

}
